package slw.controls
{
	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	import flash.utils.getDefinitionByName;
	
	import slw.core.UIComponent;
	import slw.events.LabelButtonEvent;
	
	/**
	 * LabelButton
	 * 可选中的标签按钮类，支持文本与图标(显示对象，显示对象类字符串，图片url)，支持外部图片皮肤和影片皮肤,<br/>
	 * @author ddx<br/>
	 * 2011-7-25
	 *
	 */
	public class LabelButton extends BaseButton
	{
		/**
		 * "top"图标位于顶部 
		 */		
		public static const TOP:String="top";
		/**
		 * "bottom"图标位于底部  
		 */		
		public static const BOTTOM:String="bottom";
		/**
		 * "left"图标位于左边 
		 */		
		public static const LEFT:String="left";
		/**
		 * "right"图标位于右边 
		 */		
		public static const RIGHT:String="right";
		//标签文本
		private var _text:String=null;
		//文本与图标间隔
		private var _gap:Number=5;
		//文本
		private var _textField:TextField;
		//图标显示对象
		private var _icon:DisplayObject
		//图标对象类字符串
		private var _iconStr:String=null;
		//图标地址
		private var _iconURL:String=null;
		//图标位置
		private var _position:String="";
		//文本格式
		private var _format:TextFormat;
		//默认文本格式
		private var _defaultFormat:TextFormat;
		//文本颜色
		private var _textColor:uint=0x0;
		//当autoSize=true时，文本或图标与边框的距离
		private var _padding:Number=5;
		//是否自动适应文本和图标宽高
		private var _autoSize:Boolean;
		//按钮是否选中
		private var _selected:Boolean;
		//是否自动切换选中和未选中状态
		private var _toggle:Boolean;
		//按钮相关数据
		private var _data:Object;
		/**
		 * 构造函数 
		 * @param label:String="Label" 按钮文本
		 * 
		 */		
		public function LabelButton(label:String="Label")
		{
			super();
			this.listName="Button";
			
			setProperties(label,null,LEFT);
		}
		/*
		-----------------------------------
		setters getters
		-----------------------------------
		*/
		//
		/**
		 * autoSize=true时，文本或图标与边框的距离,默认值:5px, autoSize=false时忽略此属性
		 * @param value:Number
		 * 
		 */		
		public function set padding(value:Number):void{
			if(_padding==value) return;
			
			_padding=value;
			
			updateDisplayList();
		}
		//
		/**
		 * autoSize=true时，文本或图标与边框的距离,默认值:5px, autoSize=false时忽略此属性
		 * @param value:Number
		 * 
		 */
		public function get padding():Number{
			return _padding;
		}
		//
		/**
		 * 文本与图标间隔，默认值:5px
		 * @param value:Number
		 * 
		 */		
		public function set gap(value:Number):void{
			if(_gap==value) return;
			
			_gap=value;
			updateDisplayList();
		}
		//
		/**
		 * 文本与图标间隔，默认值:5px
		 * @param value:Number
		 * 
		 */
		public function get gap():Number{
			return _gap;
		}
		//
		/**
		 * 自动适应文本和图标宽高，默认值:false
		 * @param value:Boolean
		 * 
		 */		
		public function set autoSize(value:Boolean):void{
			if(_autoSize==value){
				return;
			}
			_autoSize=value;
			
			updateDisplayList();
		}
		//
		/**
		 * 自动适应文本和图标宽高，默认值:false
		 * @param value:Boolean
		 * 
		 */
		public function get autoSize():Boolean{
			return _autoSize;
		}
		//
		/**
		 * 按钮是否选中，选中时与按下状态相同，当toggle=true时此属性才有效,默认值:false 
		 * @param value:Boolean
		 * 
		 */		
		public function set selected(value:Boolean):void{
			if(!_toggle) return;
			if(_selected==value) return;
			
			_selected=value;
			
			if(_selected){
				this.setState(DOWN);
			}else{
				this.setState(UP);
			}
			
			this.dispatchEvent(new LabelButtonEvent(LabelButtonEvent.SELECTED_CHANGE,true,true,_selected,_data));
		}
		//
		/**
		 * 按钮是否选中，选中时与按下状态相同，当toggle=true时此属性才有效,默认值:false 
		 * @param value:Boolean
		 * 
		 */	
		public function get selected():Boolean{
			return _selected;
		}
		//
		/**
		 * 按钮是否自动切换选中和未选中状态，默认值:false 
		 * @param value:Boolean
		 * 
		 */		
		public function set toggle(value:Boolean):void{
			if(_toggle==value) return;
			
			_toggle=value;
			
			if(_toggle){
				addListeners();
			}else{
				removeListeners();
			}
		}
		//
		/**
		 * 按钮是否自动切换选中和未选中状态，默认值:false 
		 * @param value:Boolean
		 * 
		 */
		public function get toggle():Boolean{
			return _toggle;
		}
		//
		/**
		 * 默认文本格式，同TextField.defaultTextFormat
		 * @param value:TextFormat
		 * 
		 */		
		public function set defaultTextFormat(value:TextFormat):void{
			if(_defaultFormat==value){
				return;
			}
			_defaultFormat=value;
			if(_textField!=null)
				_textField.defaultTextFormat=_defaultFormat;
			_format=null;
			
			updateDisplayList();
		}
		//
		/**
		 * 默认文本格式，同TextField.defaultTextFormat
		 * @param value:TextFormat
		 * 
		 */
		public function get defaultTextFormat():TextFormat{
			return _defaultFormat;
		}
		//
		/**
		 * 文本颜色 默认值:0x0
		 * @param value:uint
		 * 
		 */		
		public function set textColor(value:uint):void{
			if(_textColor==value){
				return;
			}
			_textColor=value;
			if(_textField!=null)
				_textField.textColor=_textColor;
		}
		//
		/**
		 * 文本颜色 默认值:0x0
		 * @param value:uint
		 * 
		 */	
		public function get textColor():uint{
			return _textColor;
		}
		//
		/**
		 * 标签文本,默认值:"Button"，设置值为""或null时删除文本对象
		 * @param value:String
		 * 
		 */		
		public function set label(value:String):void{
			if(_text==value){
				return;
			}
			_text=value;
			if(_text==""||_text==null){
				if(_textField!=null)
					this.buildContainer.removeChild(_textField);
				_textField=null;
			}else if(_textField==null){
				_textField=new TextField();
				_textField.autoSize=TextFieldAutoSize.LEFT;
				_textField.textColor=_textColor;
				if(_defaultFormat!=null)
					_textField.defaultTextFormat=_defaultFormat;
				this.buildContainer.addChild(_textField);
			}
			
			updateDisplayList();
		}
		//
		/**
		 * 标签文本,默认值:"Button"，设置值为""或null时删除文本对象
		 * @param value:String
		 * 
		 */
		public function get label():String{
			return _text;
		}
		//
		/**
		 * 按钮相关的数据对象,默认值:null
		 * @param value:Object
		 * 
		 */		
		public function set data(value:Object):void{
			if(_data==value) return;
			
			_data=value;
		}
		//
		/**
		 * 按钮相关的数据对象,默认值:null 
		 * @param value:Object
		 * 
		 */
		public function get data():Object{
			return _data;
		}
		//
		/**
		 * 按钮图标，值为显示对象或显示对象类字符串，设置为null时删除图标,默认值:null
		 * @param value:*
		 * 
		 */		
		public function set icon(value:*):void{
			if(_icon==value||((value is String)&&_iconStr==value)){
				return;
			}
			if(_icon!=null)
				this.buildContainer.removeChild(_icon);
			
			_icon=null;
			_iconStr=null;
			if(value is String){
				_iconStr=value;
				
				var $c:Class=getDefinitionByName(_iconStr) as Class;
				_icon=new $c();
			}else{
				_icon=value;
			}
			if(_icon!=null){
				this.buildContainer.addChild(_icon);
			}else{
				_iconURL=null;
			}
			
			updateDisplayList();
		}
		//
		/**
		 * 按钮图标，值为显示对象或显示对象类字符串，设置为null时删除图标,默认值:null
		 * @param value:*
		 * 
		 */
		public function get icon():*{
			return _icon==null?_iconStr:_icon;
		}
		//
		/**
		 * 图标URL，加载指定资源后，icon属性值设置为加载到的根显示对象(用Loader加载,参看Loader.content属性)
		 * @param value:String
		 * @see <br/>
		 * <a href='http://help.adobe.com/zh_CN/FlashPlatform/reference/actionscript/3/flash/display/Loader.html#contentLoaderInfo' target='_blank'>Loader.content</a>
		 * 
		 */				
		public function set iconURL(value:String):void{
			if(_iconURL==value){
				return;
			}
			_iconURL=value;
			
			if(_iconURL!=null){
				var $context:LoaderContext=new LoaderContext();
				$context.applicationDomain=ApplicationDomain.currentDomain;
				var $loader:Loader=new Loader();
				$loader.contentLoaderInfo.addEventListener(Event.COMPLETE,loaderComplete);
				$loader.load(new URLRequest(_iconURL),$context);
			}
		}
		//
		/**
		 * 图标URL，加载指定资源后，icon属性值设置为加载到的根显示对象(用Loader加载,参看Loader.content属性)
		 * @param value:String
		 * @see <br/>
		 * <a href='http://help.adobe.com/zh_CN/FlashPlatform/reference/actionscript/3/flash/display/Loader.html#contentLoaderInfo' target='_blank'>Loader.content</a>
		 * 
		 */	
		public function get iconURL():String{
			return _iconURL;
		}
		//
		/**
		 * 图标的位置，默认值:LabelButton.LEFT,可能的值为:<br/>
		 * <ul>
		 * 	<li>LabelButton.TOP 图标位于标签顶部<br/>
		 * 	<li>LabelButton.BOTTOM 图标位于标签底部<br/>
		 * 	<li>LabelButton.LEFT 图标位于标签左边<br/>
		 * 	<li>LabelButton.RIGHT 图标位于标签右边<br/>
		 * </ul> 
		 * @param value:String
		 * 
		 */		
		public function set position(value:String):void{
			if(_position==value){
				return;
			}
			_position=value;
			
			updateDisplayList();
		}
		//
		/**
		 * 图标的位置，默认值:LabelButton.LEFT,可能的值为:<br/>
		 * <ul>
		 * 	<li>LabelButton.TOP 图标位于标签顶部<br/>
		 * 	<li>LabelButton.BOTTOM 图标位于标签底部<br/>
		 * 	<li>LabelButton.LEFT 图标位于标签左边<br/>
		 * 	<li>LabelButton.RIGHT 图标位于标签右边<br/>
		 * </ul> 
		 * @param value:String
		 * 
		 */	
		public function get position():String{
			return _position;
		}
		//
		/**
		 * 按钮文本对象引用 
		 * @return 
		 * 
		 */		
		public function get textField():TextField{
			return _textField;
		}
		/*
		-----------------------------------
		public  methods
		-----------------------------------
		*/
		//
		/**
		 * 设置标签文本格式
		 * @param format:TextFormat
		 * 
		 */		
		public function setTextFormat(format:TextFormat):void{
			_format=format;
			
			updateDisplayList();
		}
		//
		override public function destroy():void{
			removeListeners();
			super.destroy();
		}
		/*
		-----------------------------------
		private  methods
		-----------------------------------
		*/
		//初始化
		private function init():void{
			this.mouseChildren=false;
		}
		//添加侦听
		private function addListeners():void{
			this.addEventListener(MouseEvent.CLICK,thisClick);
			this.addEventListener(MouseEvent.MOUSE_OUT,thisMouseOut);
		}
		//删除侦听
		private function removeListeners():void{
			this.removeEventListener(MouseEvent.CLICK,thisClick);
			this.removeEventListener(MouseEvent.MOUSE_OUT,thisMouseOut);
		}
		//点击
		private function thisClick(e:MouseEvent):void{
			this.selected=!this.selected;
			
			if(!this.selected)
				this.setState(OVER);
		}
		//鼠标移出
		private function thisMouseOut(e:MouseEvent):void{
			if(this.selected)
				this.setState(DOWN);
		}
		//设置主要属性
		private function setProperties(text:String,icon:*,position:String):void{
			_position=position;
			this.label=text;
			
			this.icon=icon;
			
			updateDisplayList();
		}
		//更新显示
		private function updateDisplayList():void{
			if(_textField!=null){
				_textField.text=_text==null?"":_text;
					
				if(_format!=null)
					_textField.setTextFormat(_format);
			}
			if(_autoSize){
				checkoutSize();
				
				if(_textField!=null){
					_textField.x=_padding;
					_textField.y=_padding;
				}
				if(_icon!=null){
					_icon.x=_padding;
					_icon.y=_padding;
				}
				
				if(_icon!=null&&_textField!=null){
					switch(_position){
						case TOP:
							_textField.y=_icon.y+_icon.height+_gap;
							layoutX(_textField,_icon);
							break;
						case BOTTOM:
							_icon.y=_textField.y+_textField.height+_gap;
							layoutX(_textField,_icon);
							break;
						case LEFT:
							_textField.x=_icon.x+_icon.width+_gap;
							layoutY(_textField,_icon);
							break;
						case RIGHT:
							_icon.x=_textField.x+_textField.width+_gap;
							layoutY(_textField,_icon);
							break;
					}
				}
			}else{
				if(_icon!=null&&_textField!=null){
					if(_icon!=null&&_textField!=null){
						switch(_position){
							case TOP:
								layoutYAsOne(_icon,_textField);
								layoutX(_textField,_icon);
								break;
							case BOTTOM:
								layoutYAsOne(_textField,_icon);
								layoutX(_textField,_icon);
								break;
							case LEFT:
								layoutXAsOne(_icon,_textField);
								layoutY(_textField,_icon);
								break;
							case RIGHT:
								layoutXAsOne(_textField,_icon);
								layoutY(_textField,_icon);
								break;
						}
					}
				}else if(_textField!=null&&_icon==null){
					layoutX(_textField);
					layoutY(_textField);
				}else if(_icon!=null&&_textField==null){
					layoutX(_icon);
					layoutY(_icon);
				}
			}
		}
		//x轴对齐,所有元素在x轴上对齐
		private function layoutX(...args):void{
			for(var i:int=0;i<args.length;i++){
				if(args[i].width<this.width){
					args[i].x=(this.width-args[i].width)/2;
				}
			}
		}
		//y轴对齐,所有元素在y轴上对齐
		private function layoutY(...args):void{
			for(var i:int=0;i<args.length;i++){
				if(args[i].height<this.height){
					args[i].y=(this.height-args[i].height)/2;
				}
			}
		}
		//y轴对齐,所有元素高度相加后，作为一个整体在y轴上对齐
		private function layoutYAsOne(...args):void{
			var $height:Number=0;
			for(var i:int=0;i<args.length;i++){
				$height+=DisplayObject(args[i]).height+_gap;
			}
			if(args.length>0) $height-=_gap;
			
			if(args[0]!=null) DisplayObject(args[0]).y=(this.height-$height)/2;
			
			for(var j:int=1;j<args.length;j++){
				DisplayObject(args[j]).y=DisplayObject(args[j-1]).y+DisplayObject(args[j-1]).height+_gap;
			}
		}
		//x轴对齐,所有元素宽度相加后，作为一个整体在y轴上对齐
		private function layoutXAsOne(...args):void{
			var $width:Number=0;
			for(var i:int=0;i<args.length;i++){
				$width+=DisplayObject(args[i]).width+_gap;
			}
			if(args.length>0) $width-=_gap;
			
			if(args[0]!=null) DisplayObject(args[0]).x=(this.width-$width)/2;
			
			for(var j:int=1;j<args.length;j++){
				DisplayObject(args[j]).x=DisplayObject(args[j-1]).x+DisplayObject(args[j-1]).width+_gap;
			}
		}
		//加载资源完成
		private function loaderComplete(e:Event):void{
			e.target.removeEventListener(Event.COMPLETE,loaderComplete);
			if(_iconURL!=null)
				this.icon=LoaderInfo(e.target).content;
		}
		//检测高宽
		private function checkoutSize():void{
			var $width:Number=_padding*2;
			var $height:Number=_padding*2;
			
			if(_textField!=null&&_icon!=null){
				switch(_position){
					case TOP:
					case BOTTOM:
						$width+=Math.max(_icon.width,_textField.width);
						$height+=_icon.height+_gap+_textField.height;
						break;
					case LEFT:
					case RIGHT:
						$width+=_icon.width+_gap+_textField.width;
						$height+=Math.max(_icon.height,_textField.height);
						break;
				}
			}else if(_icon!=null){
				$width+=_icon.width;
				$height+=_icon.height;
			}else if(_textField!=null){
				$width+=_textField.width;
				$height+=_textField.height;
			}
			
			this.width=$width;
			this.height=$height;
		}
	}
}